<template>
  <div class="container">
    <div class="title_bar">
      <div class="main_title">销量统计表</div>
      <div class="sub_title">1901 - 1914 服装销量统计表</div>
      <slot name="title"></slot>
    </div>
    <div id="pie_basic" style="width: 100%"></div>
    <div class="buttonWrapper">
      <el-button type="primary" @click="changeLabelType(0)"> 默认</el-button>
      <el-button type="primary" @click="changeLabelType(1)"> 图内 label </el-button>
      <el-button type="primary" @click="changeLabelType(2)"> 蜘蛛 label </el-button>
      <el-button type="primary" @click="changeLabelType(3)"> 自定义形状/内容 </el-button>
    </div>
  </div>
</template>

<script>
import { Chart , getEngine } from "@antv/g2";
import { DataView } from "@antv/data-set";
const imageMap = {
  "衣服": require("/src/assets/icon_image/衬衣.png"),
  "裤子": require("/src/assets/icon_image/裤装.png"),
  "衬衫": require("/src/assets/icon_image/T 恤.png"),
  "毛衣": require("/src/assets/icon_image/卫衣.png"),
  "T恤":  require("/src/assets/icon_image/T 恤.png"),
  "围巾": require("/src/assets/icon_image/围巾.png"),
  "礼帽": require("/src/assets/icon_image/礼帽.png"),
  "鞋": require("/src/assets/icon_image/鞋.png")
}
export default {
  data() {
    return {
      chart: null,
      dataList: [
        { label: "衣服", nums: 28 },
        { label: "裤子", nums: 32 },
        { label: "衬衫", nums: 40 },
        { label: "毛衣", nums: 18 },
        { label: "T恤", nums: 52 },
        { label: "围巾", nums: 15 },
      ],
    };
  },
  created() {
    // 模拟数据变化
      setTimeout(() => {
        this.dataList.push(
          { label: "礼帽", nums: 8 },
          { label: "鞋", nums: 11 }
        );
      }, 2000);
  },
  mounted() {
    this.chart = new Chart({
      // 指定图表容器 ID
      container: "pie_basic",
      // 自适应宽度，容器伸缩会重新渲染图表
      autoFit: true,
      // 容器的高度
      height: 500,
      // 图表的外侧内边距
      padding: [40, 80, 80, 80],
    });

    // 给图表赋值
    this.chart.data(this.transformData(this.dataList));
    // 设置提示信息
    this.chart.tooltip({
      showMarkers: false,
    });
    // 设置 nums 度量，重新格式化数据
    this.chart.scale("nums", {
      formatter(val) {
        return val + "万件";
      },
    });
    // 使用交互效果
    this.chart.interaction("element-highlight");
    // 设置坐标系为 theta
    this.chart.coordinate("theta", {
      radius: 0.75,
    });
    // 映射图表
    this.chart
      .interval()
      .position("nums")
      .color("label")
      // 设置数据标签
      .label("nums", {
        // 自定义内容
        content: (data) => {
          return `${data.label}: ${data.percent}%`;
        },
      })
      // 设置为层叠，让总值占满整个圆
      // 不设置层叠会以值最大的占满整个圆，其他项照此比例覆盖
      .adjust("stack");
    this.chart.render();
  },
  watch: {
    // 监听图表变化更新数据
    dataList(newValue) {
      console.log(newValue);
      this.chart.changeData( this.transformData(newValue) );
    },
  },
  methods: {
    // 计算每一项所占百分比
    transformData(data) {
      const dv = new DataView().source(data);
      const total = data.reduce((pre, item) => pre + item.nums, 0);
      dv.transform({
        type: "map",
        callback(row) {
          row.percent = +((row.nums * 100) / total).toFixed(2);
          return row;
        },
      });
      return dv.rows;
    },
    // 更换图表 label 样式
    changeLabelType(type){
      const G = getEngine('canvas');
      this.chart.clear();
      const geo = this.chart
          .interval()
          .position("nums")
          .color("label")
          .adjust("stack");
      switch (type){
        // 初始label
        case 0 :
          geo.label("nums", {
            // 自定义内容
            content: (data) => {
              return `${data.label}: ${data.percent}%`;
            },
          })
          break;
        // 图内 label
        case 1 :
         geo.label("nums", {
            content: (data) => {
              return `${data.percent}%`;
            },
            // 位置移动
            offset: '-30%',
            // 配置文字样式
            style: {
              textAlign: 'center',
              fontSize: 16,
              shadowBlur: 2,
              shadowColor: 'rgba(0, 0, 0, .45)',
            },
          })
          break;
        // 蜘蛛 label
        case 2: 
          geo.label("nums",{
            content: (data) => {
              return `${data.label}: ${data.percent}%`;
            },
            // 设置 label 布局 适合超多数据表
            layout: { type: 'pie-spider' },
            // label 线的长度
            labelHeight: 20,
            // 设置连接线
            labelLine: {
              style: {
                // 线宽 0.5
                lineWidth: 0.5,
              },
            },
          })
          break;
        // 自定义形状/内容
        case 3:
          geo.label("label",{
            content:(obj,item) =>{
              // 获取 label 图形坐标
              const [x0, x1] = item.x || [0, 0];
              // 判断是否在上半部
              const isTop = x0 < x1;
              // 创建一个图形组
              const group = new G.Group({});
              // 给该组添加图片图形
                group.addShape({
                type: 'image',
                attrs: {
                  x: 6,
                  y: isTop ? -20 : 20,
                  textAlign:"center",
                  width: 30,
                  height: 30,
                  img: imageMap[obj.label]
                },
              });
              // 给该组添加文字图形
               group.addShape({
                type: 'text',
                attrs: {
                  x: 20,
                  y: isTop ? 10 : 60,
                  text: obj.label,
                  textAlign:'center',
                  textBaseline: 'top',
                  fill: 'rgba(0, 0, 0, 0.65)',
                  fontWeight: 700,
                  fontSize: 14,
                },
              });
              return group
            },
            // 设置 label 整体的位置
            offsetX:0,
            offsetY:0,
          })
          break;
      }
      this.chart.render();
    }
  },
};
</script>

<style lang="scss" scoped>
.container {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  .title_bar {
    width: 100%;
    margin-bottom: 20px;
    .main_title {
      width: 100%;
      text-align: center;
      font-size: 40px;
      color: #333333;
    }
    .sub_title {
      width: 100%;
      text-align: center;
      font-size: 28px;
      margin-top: 18px;
      color: #999999;
    }
  }
}
</style>